dgb(#82 4b/4c): wire regrind seam into forced-won soak driver (--soak-regrind) [HOLD] - #287
Closed
frstrtr wants to merge 6 commits into
Closed
dgb(#82 4b/4c): wire regrind seam into forced-won soak driver (--soak-regrind) [HOLD]#287frstrtr wants to merge 6 commits into
frstrtr wants to merge 6 commits into
Conversation
Land the foundational slice of embedded real work-gen: coin/scrypt_pow.hpp wraps btclibs scrypt_1024_1_1_256(80-byte header) and decodes the 32-byte digest via the existing u256::from_le_bytes (dgb_arith256.hpp), closing the documented "the scrypt CALL itself lands at the ingest boundary in a following slice" TODO. Single SSOT so the nonce grinder (next slice) and the header_chain ingest boundary can never disagree on PoW byte order. V36 Scrypt-only: this is the ONLY PoW digest DGB validates; the other four algos are accept-by-continuity and never reach here. dgb_scrypt_pow_test (5/5): pins the digest bytes over a fixed header (vector captured from btclibs scrypt itself, the DGB-Scrypt algo SSOT) and proves the little-endian decode compares correctly against SetCompact-shaped targets the way header_chain.hpp satisfaction gate does (pow_hash <= target, MSB-first). Reuses header_chain_test scrypt TU set (real scrypt, header-only u256, no core / no OBJECT lib). Registered in CMake + both build.yml --target allowlists. End-to-end agreement with DigiByte Core is proven by the live node-B ACCEPT integration test (4b/4c tip-extension bar), not this unit KAT.
grind_won_nonce(header80, target) increments the 80-byte header nonce [76..79] LE until scrypt_pow_hash(header) <= target -- the EXACT header_chain.hpp satisfaction gate -- calling THROUGH the #286 digest CALL SSOT (never a bypass hash), so a nonce it accepts is one node B ACCEPTs. This is the missing primitive between the faithful won-block reconstruction and a ProcessNewBlock ACCEPT: the leg-2 A/B delivery proof reached node B but was consensus-rejected high-hash precisely because the forced-won seam carried no real PoW. Fails closed: returns nullopt when no nonce satisfies inside the budget (or the full 2^32 space wraps) -- a header that does not satisfy its target is never broadcast, mirroring the reconstructor loud-throw. dgb_nonce_grinder_test (5/5): finds a satisfying nonce well inside budget, the winning header satisfies the gate and its reported digest == the SSOT digest, the winning nonce is written LE into [76..79], re-grinding from the winner succeeds on iter 1, and an unsatisfiable target exhausts the budget to nullopt. Reuses the _dgb_scrypt_tus real-scrypt set; header-only u256, no core / no dgb OBJECT lib. Added to both build.yml --target allowlists. Fenced src/impl/dgb/ + build.yml. Wiring grind -> reconstruct -> submit on the live forced-won path and the node-B ACCEPT gate proof are the explicitly-next integration slice.
…KAT)
regrind_block_nonce: grind the header nonce of an ALREADY-FRAMED
reconstructed-block blob (reconstruct_won_block_from_template {bytes})
until its DGB-Scrypt PoW digest satisfies the parent target, writing the
winning nonce back into header [76..79] IN PLACE. The missing wiring
between the faithful won-block reconstruction (merkle root fixed) and a
node-B ProcessNewBlock ACCEPT: the A/B delivery proof reached node B but
was consensus-rejected "high-hash" because the forced-won seam carried
no real PoW.
Ordering invariant enforced structurally: runs only on an already-framed
block (merkle root set FIRST by reconstruct), mutates ONLY header bytes
[76..79], never the merkle region [36..67] or tx tail. Hash via the #286
scrypt_pow_hash SSOT only; satisfaction = the exact pow <= target gate
header_chain.hpp runs. Fail-closed (nullopt, bytes UNCHANGED) on a runt
blob or exhausted budget.
KAT 5/5: reground header satisfies target via SSOT; only [76..79] mutate
(merkle + tx tail byte-preserved); runt-blob fail-closed; exhausted-budget
fail-closed; deterministic. Reuses the _dgb_scrypt_tus real-scrypt set;
header-only, no core / no OBJECT lib. Both build.yml --target allowlists.
Per-coin isolation: src/impl/dgb/ only. p2pool-merged-v36 surface: NONE.
Closes the #82 broadcaster dual-path gate on the wire: live UpdateTip won block (regtest diff, no test-only seam) -> reconstruct coinbase-only -> ARM A submit_block_p2p_raw relays to a peer node, asserting PROP1 (coinbase-only accepted, not fail-open) + PROP2/ARM-A (P2P reaches network). Scripts-only, fenced (scripts/), DGB-isolated, localhost regtest, self-service creds. Two live-leg items remain: digibyted self-provisioning (daemon-gated, only namecoind on fleet) and ARM B submitblock-fallback isolation mechanism (no --no-p2p-relay flag -> integrator design call), both explicit in-file.
Approved operator toggle (integrator UID1709, option a): suppress ONLY the embedded P2P-relay arm in main_dgb on_block_found, leaving the external-digibyted submitblock seam (RPC fallback) live. Lets the #82 regtest soak prove the submitblock fallback lands the won block on its own, deterministically, instead of being masked by a silent or dead P2P relay -- the historical #82 gap. Additive, DGB-fenced (src/c2pool/main_dgb.cpp only); no consensus/share/ PPLNS/shared surface. Real operator flag, not a test-only seam (mirrors the no-test-seam principle honored for ARM A).
…-regrind) The forced-won soak reconstructs a block from an injected won share that carries no real Scrypt work, so node B rejects it high-hash. --soak-regrind (default OFF, absent from every prod path) wraps the faithful reconstruct closure: after the version-agnostic template reconstruct frames the block, it grinds header[76..79] via regrind_block_nonce until the DGB-Scrypt digest satisfies the block's OWN declared nBits -- exactly the target node B validates -- then recomputes the hex so both broadcast arms carry the ground bytes. Merkle root and tx tail are untouched. This closes the last gap to a live A/B node-B ACCEPT: the seam (PR #286) was a library + KAT; this lands it in the run-loop behind an explicit operator-only flag. build EXIT=0, --selftest EXIT=0, --help advertises --soak-regrind.
Owner
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Wires the #286 grind->reconstruct->submit regrind seam into the run-loop forced-won soak driver behind a new operator-only flag
--soak-regrind(default OFF; absent from every production path).When set, the faithful template-reconstruct closure is wrapped: after the block is framed,
regrind_block_noncegrinds header[76..79] until the DGB-Scrypt digest satisfies the block's own declared nBits (the exact target node B validates), then the hex is recomputed so BOTH broadcast arms (embedded P2P relay + submitblock fallback) carry the ground bytes. Merkle root + tx tail untouched.Why
A forced-won soak share carries no real Scrypt work, so the reconstructed block is rejected high-hash by node B (the documented gate on the live A/B ACCEPT proof). #286 landed the grind seam as library + KAT; this lands it in
main_dgb.cpp --run, closing the last gap to a node-B ACCEPT end to end.Scope / safety
src/c2pool/main_dgb.cpp), fenced to DGB.--soak-regrindOFF by default -> zero production behaviour change; genuine pool-won shares already satisfy the parent target and are NEVER reground.--selftestEXIT=0,--helpadvertises the flag.Stacking
Stacks on #286 (regrind seam + scrypt_pow SSOT, integrator-approved UID1727) and the #282 soak harness (cherry-picked here). Land #286 first, then this.
HOLD merge — integrator merges with operator 'push approved'. Next: run live regtest A/B with
--soak-regrindand capture the node-B ACCEPT.